﻿using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

namespace Vanara.PInvoke
{
	/// <summary>Specifies characteristics for the device.</summary>
	[PInvokeData("wdm.h")]
	[Flags]
	public enum CM_FILE : uint
	{
		FILE_REMOVABLE_MEDIA = 0x00000001,
		FILE_READ_ONLY_DEVICE = 0x00000002,
		FILE_FLOPPY_DISKETTE = 0x00000004,
		FILE_WRITE_ONCE_MEDIA = 0x00000008,
		FILE_REMOTE_DEVICE = 0x00000010,
		FILE_DEVICE_IS_MOUNTED = 0x00000020,
		FILE_VIRTUAL_VOLUME = 0x00000040,
		FILE_AUTOGENERATED_DEVICE_NAME = 0x00000080,
		FILE_DEVICE_SECURE_OPEN = 0x00000100,
		FILE_CHARACTERISTIC_PNP_DEVICE = 0x00000800,
		FILE_CHARACTERISTIC_TS_DEVICE = 0x00001000,
		FILE_CHARACTERISTIC_WEBDAV_DEVICE = 0x00002000,
		FILE_CHARACTERISTIC_CSV = 0x00010000,
		FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL = 0x00020000,
		FILE_PORTABLE_DEVICE = 0x00040000,
	}

	/// <summary>
	/// Contains flag bits that are specific to the resource type, as indicated in the following table. Flags can be bitwise-ORed together
	/// as appropriate.
	/// </summary>
	[PInvokeData("wdm.h")]
	[Flags]
	public enum CM_RESOURCE : ushort
	{
		CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE = 0x00,
		CM_RESOURCE_INTERRUPT_LATCHED = 0x01,
		CM_RESOURCE_INTERRUPT_MESSAGE = 0x02,
		CM_RESOURCE_INTERRUPT_POLICY_INCLUDED = 0x04,
		CM_RESOURCE_INTERRUPT_SECONDARY_INTERRUPT = 0x10,
		CM_RESOURCE_INTERRUPT_WAKE_HINT = 0x20,
		CM_RESOURCE_INTERRUPT_LEVEL_LATCHED_BITS = 0x0001,
		CM_RESOURCE_INTERRUPT_MESSAGE_TOKEN = 0xFFFE,
		CM_RESOURCE_MEMORY_READ_WRITE = 0x0000,
		CM_RESOURCE_MEMORY_READ_ONLY = 0x0001,
		CM_RESOURCE_MEMORY_WRITE_ONLY = 0x0002,
		CM_RESOURCE_MEMORY_WRITEABILITY_MASK = 0x0003,
		CM_RESOURCE_MEMORY_PREFETCHABLE = 0x0004,
		CM_RESOURCE_MEMORY_COMBINEDWRITE = 0x0008,
		CM_RESOURCE_MEMORY_24 = 0x0010,
		CM_RESOURCE_MEMORY_CACHEABLE = 0x0020,
		CM_RESOURCE_MEMORY_WINDOW_DECODE = 0x0040,
		CM_RESOURCE_MEMORY_BAR = 0x0080,
		CM_RESOURCE_MEMORY_COMPAT_FOR_INACCESSIBLE_RANGE = 0x0100,
		CM_RESOURCE_MEMORY_LARGE = 0x0E00,
		CM_RESOURCE_MEMORY_LARGE_40 = 0x0200,
		CM_RESOURCE_MEMORY_LARGE_48 = 0x0400,
		CM_RESOURCE_MEMORY_LARGE_64 = 0x0800,
		CM_RESOURCE_PORT_MEMORY = 0x0000,
		CM_RESOURCE_PORT_IO = 0x0001,
		CM_RESOURCE_PORT_10_BIT_DECODE = 0x0004,
		CM_RESOURCE_PORT_12_BIT_DECODE = 0x0008,
		CM_RESOURCE_PORT_16_BIT_DECODE = 0x0010,
		CM_RESOURCE_PORT_POSITIVE_DECODE = 0x0020,
		CM_RESOURCE_PORT_PASSIVE_DECODE = 0x0040,
		CM_RESOURCE_PORT_WINDOW_DECODE = 0x0080,
		CM_RESOURCE_PORT_BAR = 0x0100,
		CM_RESOURCE_DMA_8 = 0x0000,
		CM_RESOURCE_DMA_16 = 0x0001,
		CM_RESOURCE_DMA_32 = 0x0002,
		CM_RESOURCE_DMA_8_AND_16 = 0x0004,
		CM_RESOURCE_DMA_BUS_MASTER = 0x0008,
		CM_RESOURCE_DMA_TYPE_A = 0x0010,
		CM_RESOURCE_DMA_TYPE_B = 0x0020,
		CM_RESOURCE_DMA_TYPE_F = 0x0040,
		CM_RESOURCE_DMA_V3 = 0x0080,
		DMAV3_TRANFER_WIDTH_8 = 0x00,
		DMAV3_TRANFER_WIDTH_16 = 0x01,
		DMAV3_TRANFER_WIDTH_32 = 0x02,
		DMAV3_TRANFER_WIDTH_64 = 0x03,
		DMAV3_TRANFER_WIDTH_128 = 0x04,
		DMAV3_TRANFER_WIDTH_256 = 0x05,
		CM_RESOURCE_CONNECTION_CLASS_GPIO = 0x01,
		CM_RESOURCE_CONNECTION_CLASS_SERIAL = 0x02,
		CM_RESOURCE_CONNECTION_CLASS_FUNCTION_CONFIG = 0x03,
		CM_RESOURCE_CONNECTION_TYPE_GPIO_IO = 0x02,
		CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C = 0x01,
		CM_RESOURCE_CONNECTION_TYPE_SERIAL_SPI = 0x02,
		CM_RESOURCE_CONNECTION_TYPE_SERIAL_UART = 0x03,
		CM_RESOURCE_CONNECTION_TYPE_FUNCTION_CONFIG = 0x01,
	}

	/// <summary>Indicates whether the described resource can be shared.</summary>
	[PInvokeData("wdm.h")]
	public enum CM_SHARE_DISPOSITION : byte
	{
		/// <summary>Undetermined.</summary>
		CmResourceShareUndetermined = 0,

		/// <summary>The device requires exclusive use of the resource.</summary>
		CmResourceShareDeviceExclusive,

		/// <summary>The driver requires exclusive use of the resource. (Not supported for WDM drivers.)</summary>
		CmResourceShareDriverExclusive,

		/// <summary>The resource can be shared without restriction.</summary>
		CmResourceShareShared
	}

	/// <summary>
	/// Identifies the resource type. The constant value specified for Type indicates which structure within the u union is valid, as
	/// indicated in the following table. (These flags are used within both CM_PARTIAL_RESOURCE_DESCRIPTOR and IO_RESOURCE_DESCRIPTOR
	/// structures, except where noted.)
	/// </summary>
	[PInvokeData("wdm.h")]
	[Flags]
	public enum CmResourceType : byte
	{
		/// <summary>No value is set.</summary>
		CmResourceTypeNull = 0,

		/// <summary>u.Port</summary>
		CmResourceTypePort = 1,

		/// <summary>
		/// u.Interrupt or u.MessageInterrupt. If the CM_RESOURCE_INTERRUPT_MESSAGE flag of Flags is set, use u.MessageInterrupt; otherwise,
		/// use u.Interrupt.
		/// </summary>
		CmResourceTypeInterrupt = 2,

		/// <summary>u.Memory</summary>
		CmResourceTypeMemory = 3,

		/// <summary>u.Dma (if CM_RESOURCE_DMA_V3 is not set) or u.DmaV3 (if CM_RESOURCE_DMA_V3 flag is set)</summary>
		CmResourceTypeDma = 4,

		/// <summary>u.DeviceSpecificData(Not used within IO_RESOURCE_DESCRIPTOR.)</summary>
		CmResourceTypeDeviceSpecific = 5,

		/// <summary>u.BusNumber</summary>
		CmResourceTypeBusNumber = 6,

		/// <summary>
		/// One of u.Memory40, u.Memory48, or u.Memory64.The CM_RESOURCE_MEMORY_LARGE_XXX flags set in the Flags member determines which
		/// structure is used.
		/// </summary>
		CmResourceTypeMemoryLarge = 7,

		/// <summary>Not used.</summary>
		CmResourceTypeNonArbitrated = 128,

		/// <summary>Reserved for system use.</summary>
		CmResourceTypeConfigData = 128,

		/// <summary>u.DevicePrivate</summary>
		CmResourceTypeDevicePrivate = 129,

		/// <summary>u.DevicePrivate</summary>
		CmResourceTypePcCardConfig = 130,

		/// <summary>u.DevicePrivate</summary>
		CmResourceTypeMfCardConfig = 131,

		/// <summary>u.Connection</summary>
		CmResourceTypeConnection = 132,
	}

	/// <summary>The <c>DEVICE_POWER_STATE</c> enumeration type indicates a device power state.</summary>
	/// <remarks>
	/// <para>
	/// A power state indicates the level of power consumption—and thus the extent of computing activity—by the system or by a single
	/// device. The power manager sets the power state of the system as a whole, where the system power state is indicated by one of the
	/// values of the SYSTEM_POWER_STATE enumeration type. Device drivers set the power state of their individual devices, where the device
	/// power state is indicated by one of the values of the <c>DEVICE_POWER_STATE</c> enumeration type.
	/// </para>
	/// <para>
	/// For more information about system power states, see Handling System Power State Requests. For more information about device power
	/// states, see Managing Power for Individual Devices. For more information about power management in general, see Introduction to Power Management.
	/// </para>
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_device_power_state typedef enum _DEVICE_POWER_STATE {
	// PowerDeviceUnspecified, PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, PowerDeviceMaximum } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
	[PInvokeData("wdm.h", MSDNShortId = "NE:wdm._DEVICE_POWER_STATE")]
	public enum DEVICE_POWER_STATE
	{
		/// <summary>Indicates an unspecified device power state.</summary>
		PowerDeviceUnspecified = 0,

		/// <summary>Indicates a maximum device power state, which corresponds to device working state D0.</summary>
		PowerDeviceD0,

		/// <summary>
		/// Indicates a device sleeping state less than PowerDeviceD0 and greater than PowerDeviceD2, which corresponds to device power
		/// state D1.
		/// </summary>
		PowerDeviceD1,

		/// <summary>
		/// Indicates a device sleeping state less than PowerDeviceD1 and greater than PowerDeviceD3, which corresponds to device power
		/// state D2.
		/// </summary>
		PowerDeviceD2,

		/// <summary>Indicates the lowest-powered device sleeping state, which corresponds to device power state D3.</summary>
		PowerDeviceD3,

		/// <summary>
		/// The number of device power state values for this enumeration type that represent actual power states. The value of the other
		/// device power states is less than this value.
		/// </summary>
		PowerDeviceMaximum,
	}

	/// <summary>The device type represents the type of underlying hardware for the driver.</summary>
	[PInvokeData("wdm.h")]
	public enum FILE_DEVICE : uint
	{
		FILE_DEVICE_BEEP = 0x00000001,
		FILE_DEVICE_CD_ROM = 0x00000002,
		FILE_DEVICE_CD_ROM_FILE_SYSTEM = 0x00000003,
		FILE_DEVICE_CONTROLLER = 0x00000004,
		FILE_DEVICE_DATALINK = 0x00000005,
		FILE_DEVICE_DFS = 0x00000006,
		FILE_DEVICE_DISK = 0x00000007,
		FILE_DEVICE_DISK_FILE_SYSTEM = 0x00000008,
		FILE_DEVICE_FILE_SYSTEM = 0x00000009,
		FILE_DEVICE_INPORT_PORT = 0x0000000a,
		FILE_DEVICE_KEYBOARD = 0x0000000b,
		FILE_DEVICE_MAILSLOT = 0x0000000c,
		FILE_DEVICE_MIDI_IN = 0x0000000d,
		FILE_DEVICE_MIDI_OUT = 0x0000000e,
		FILE_DEVICE_MOUSE = 0x0000000f,
		FILE_DEVICE_MULTI_UNC_PROVIDER = 0x00000010,
		FILE_DEVICE_NAMED_PIPE = 0x00000011,
		FILE_DEVICE_NETWORK = 0x00000012,
		FILE_DEVICE_NETWORK_BROWSER = 0x00000013,
		FILE_DEVICE_NETWORK_FILE_SYSTEM = 0x00000014,
		FILE_DEVICE_NULL = 0x00000015,
		FILE_DEVICE_PARALLEL_PORT = 0x00000016,
		FILE_DEVICE_PHYSICAL_NETCARD = 0x00000017,
		FILE_DEVICE_PRINTER = 0x00000018,
		FILE_DEVICE_SCANNER = 0x00000019,
		FILE_DEVICE_SERIAL_MOUSE_PORT = 0x0000001a,
		FILE_DEVICE_SERIAL_PORT = 0x0000001b,
		FILE_DEVICE_SCREEN = 0x0000001c,
		FILE_DEVICE_SOUND = 0x0000001d,
		FILE_DEVICE_STREAMS = 0x0000001e,
		FILE_DEVICE_TAPE = 0x0000001f,
		FILE_DEVICE_TAPE_FILE_SYSTEM = 0x00000020,
		FILE_DEVICE_TRANSPORT = 0x00000021,
		FILE_DEVICE_UNKNOWN = 0x00000022,
		FILE_DEVICE_VIDEO = 0x00000023,
		FILE_DEVICE_VIRTUAL_DISK = 0x00000024,
		FILE_DEVICE_WAVE_IN = 0x00000025,
		FILE_DEVICE_WAVE_OUT = 0x00000026,
		FILE_DEVICE_8042_PORT = 0x00000027,
		FILE_DEVICE_NETWORK_REDIRECTOR = 0x00000028,
		FILE_DEVICE_BATTERY = 0x00000029,
		FILE_DEVICE_BUS_EXTENDER = 0x0000002a,
		FILE_DEVICE_MODEM = 0x0000002b,
		FILE_DEVICE_VDM = 0x0000002c,
		FILE_DEVICE_MASS_STORAGE = 0x0000002d,
		FILE_DEVICE_SMB = 0x0000002e,
		FILE_DEVICE_KS = 0x0000002f,
		FILE_DEVICE_CHANGER = 0x00000030,
		FILE_DEVICE_SMARTCARD = 0x00000031,
		FILE_DEVICE_ACPI = 0x00000032,
		FILE_DEVICE_DVD = 0x00000033,
		FILE_DEVICE_FULLSCREEN_VIDEO = 0x00000034,
		FILE_DEVICE_DFS_FILE_SYSTEM = 0x00000035,
		FILE_DEVICE_DFS_VOLUME = 0x00000036,
		FILE_DEVICE_SERENUM = 0x00000037,
		FILE_DEVICE_TERMSRV = 0x00000038,
		FILE_DEVICE_KSEC = 0x00000039,
		FILE_DEVICE_FIPS = 0x0000003A,
		FILE_DEVICE_INFINIBAND = 0x0000003B,
		FILE_DEVICE_VMBUS = 0x0000003E,
		FILE_DEVICE_CRYPT_PROVIDER = 0x0000003F,
		FILE_DEVICE_WPD = 0x00000040,
		FILE_DEVICE_BLUETOOTH = 0x00000041,
		FILE_DEVICE_MT_COMPOSITE = 0x00000042,
		FILE_DEVICE_MT_TRANSPORT = 0x00000043,
		FILE_DEVICE_BIOMETRIC = 0x00000044,
		FILE_DEVICE_PMI = 0x00000045,
		FILE_DEVICE_EHSTOR = 0x00000046,
		FILE_DEVICE_DEVAPI = 0x00000047,
		FILE_DEVICE_GPIO = 0x00000048,
		FILE_DEVICE_USBEX = 0x00000049,
		FILE_DEVICE_CONSOLE = 0x00000050,
		FILE_DEVICE_NFP = 0x00000051,
		FILE_DEVICE_SYSENV = 0x00000052,
		FILE_DEVICE_VIRTUAL_BLOCK = 0x00000053,
		FILE_DEVICE_POINT_OF_SERVICE = 0x00000054,
		FILE_DEVICE_STORAGE_REPLICATION = 0x00000055,
		FILE_DEVICE_TRUST_ENV = 0x00000056,
		FILE_DEVICE_UCM = 0x00000057,
		FILE_DEVICE_UCMTCPCI = 0x00000058,
	}

	/// <summary>The <c>INTERFACE_TYPE</c> enumeration indicates the bus type.</summary>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ne-wdm-_interface_type typedef enum _INTERFACE_TYPE {
	// InterfaceTypeUndefined, Internal, Isa, Eisa, MicroChannel, TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, MPSABus,
	// ProcessorInternal, InternalPowerBus, PNPISABus, PNPBus, Vmcs, ACPIBus, MaximumInterfaceType } INTERFACE_TYPE, *PINTERFACE_TYPE;
	[PInvokeData("wdm.h", MSDNShortId = "4d20f3fd-d06e-420b-af69-9ef34addc611")]
	public enum INTERFACE_TYPE
	{
		/// <summary>Indicates that the interface type is undefined.</summary>
		InterfaceTypeUndefined = -1,

		/// <summary>For internal use only.</summary>
		Internal,

		/// <summary>Indicates that the interface is published by the ISA bus driver.</summary>
		Isa,

		/// <summary>Indicates that the interface is published by the EISA bus driver.</summary>
		Eisa,

		/// <summary>Indicates that the interface is published by the MicroChannel bus driver.</summary>
		MicroChannel,

		/// <summary>Indicates that the interface is published by the TurboChannel bus driver.</summary>
		TurboChannel,

		/// <summary>Indicates that the interface is published by the PCI bus driver.</summary>
		PCIBus,

		/// <summary>Indicates that the interface is published by the VME bus driver.</summary>
		VMEBus,

		/// <summary>Indicates that the interface is published by the NuBus driver.</summary>
		NuBus,

		/// <summary>Indicates that the interface is published by the PCMCIA bus driver.</summary>
		PCMCIABus,

		/// <summary>Indicates that the interface is published by the Cbus driver.</summary>
		CBus,

		/// <summary>Indicates that the interface is published by the MPI bus driver.</summary>
		MPIBus,

		/// <summary>Indicates that the interface is published by the MPSA bus driver.</summary>
		MPSABus,

		/// <summary>Indicates that the interface is published by the ISA bus driver.</summary>
		ProcessorInternal,

		/// <summary>
		/// Indicates that the interface is published for an internal power bus. Some devices have power control ports that allow them to
		/// share power control with other devices. The Windows architecture represents these devices as slots on a virtual bus called an
		/// "internal power bus."
		/// </summary>
		InternalPowerBus,

		/// <summary>Indicates that the interface is published by the PNPISA bus driver.</summary>
		PNPISABus,

		/// <summary>Indicates that the interface is published by the PNP bus driver.</summary>
		PNPBus,

		/// <summary>Reserved for use by the operating system.</summary>
		Vmcs,

		/// <summary>
		/// Indicates that the interface is published by the ACPI bus driver. The ACPI bus driver enumerates devices that are described in
		/// the ACPI firmware of the hardware platform. These devices might physically reside on buses that are controlled by other bus
		/// drivers, but the ACPI bus driver must enumerate these devices because the other bus drivers cannot detect them. This interface
		/// type is defined starting with Windows 8.
		/// </summary>
		ACPIBus,

		/// <summary>Marks the upper limit of the possible bus types.</summary>
		MaximumInterfaceType,
	}

	/// <summary>The device's power capabilities.</summary>
	[PInvokeData("wdm.h")]
	[Flags]
	public enum PDCAP : uint
	{
		/// <summary>The device supports system power state D0.</summary>
		PDCAP_D0_SUPPORTED = 0x00000001,

		/// <summary>The device supports system power state D1.</summary>
		PDCAP_D1_SUPPORTED = 0x00000002,

		/// <summary>The device supports system power state D2.</summary>
		PDCAP_D2_SUPPORTED = 0x00000004,

		/// <summary>The device supports system power state D3.</summary>
		PDCAP_D3_SUPPORTED = 0x00000008,

		/// <summary>The device supports system sleep state S0.</summary>
		PDCAP_S0_SUPPORTED = 0x00010000,

		/// <summary>The device supports system sleep state S1.</summary>
		PDCAP_S1_SUPPORTED = 0x00020000,

		/// <summary>The device supports system sleep state S2.</summary>
		PDCAP_S2_SUPPORTED = 0x00040000,

		/// <summary>The device supports system sleep state S3.</summary>
		PDCAP_S3_SUPPORTED = 0x00080000,

		/// <summary>The device supports system sleep state S4.</summary>
		PDCAP_S4_SUPPORTED = 0x01000000,

		/// <summary>The device supports system sleep state S5.</summary>
		PDCAP_S5_SUPPORTED = 0x02000000,

		/// <summary>The device supports waking from system power state D0.</summary>
		PDCAP_WAKE_FROM_D0_SUPPORTED = 0x00000010,

		/// <summary>The device supports waking from system power state D1.</summary>
		PDCAP_WAKE_FROM_D1_SUPPORTED = 0x00000020,

		/// <summary>The device supports waking from system power state D2.</summary>
		PDCAP_WAKE_FROM_D2_SUPPORTED = 0x00000040,

		/// <summary>The device supports waking from system power state D3.</summary>
		PDCAP_WAKE_FROM_D3_SUPPORTED = 0x00000080,

		/// <summary>The device supports waking from system sleep state S0.</summary>
		PDCAP_WAKE_FROM_S0_SUPPORTED = 0x00100000,

		/// <summary>The device supports waking from system sleep state S1.</summary>
		PDCAP_WAKE_FROM_S1_SUPPORTED = 0x00200000,

		/// <summary>The device supports waking from system sleep state S2.</summary>
		PDCAP_WAKE_FROM_S2_SUPPORTED = 0x00400000,

		/// <summary>The device supports waking from system sleep state S3.</summary>
		PDCAP_WAKE_FROM_S3_SUPPORTED = 0x00800000,

		/// <summary>The device supports waking from system sleep state S3.</summary>
		PDCAP_WARM_EJECT_SUPPORTED = 0x00000100,
	}

	/// <summary>
	/// <para>The <c>SYSTEM_POWER_STATE</c> enumeration type is used to indicate a system power state.</para>
	/// </summary>
	/// <remarks>
	/// <para>
	/// A power state indicates the level of power consumption—and thus the extent of computing activity—by the system or by a single
	/// device. The power manager sets the power state of the system as a whole, where the system power state is indicated by one of the
	/// values of the <c>SYSTEM_POWER_STATE</c> enumeration type. Device drivers set the power state of their individual devices, where
	/// the device power state is indicated by one of the values of the DEVICE_POWER_STATE enumeration type.
	/// </para>
	/// <para>
	/// For more information about system power states, see Handling System Power State Requests and for more information about device
	/// power states, see Managing Power for Individual Devices.
	/// </para>
	/// <para>For more information about power management in general, see Introduction to Power Management.</para>
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-system_power_state typedef enum _SYSTEM_POWER_STATE {
	// PowerSystemUnspecified, PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, PowerSystemSleeping3, PowerSystemHibernate,
	// PowerSystemShutdown, PowerSystemMaximum } SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
	[PInvokeData("wdm.h", MSDNShortId = "NE:winnt._SYSTEM_POWER_STATE")]
	public enum SYSTEM_POWER_STATE
	{
		/// <summary>Indicates an unspecified system power state.</summary>
		PowerSystemUnspecified = 0,

		/// <summary>Indicates maximum system power, which corresponds to system working state S0.</summary>
		PowerSystemWorking,

		/// <summary>
		/// Indicates a system sleeping state less than PowerSystemWorking and greater than PowerSystemSleeping2, which corresponds to
		/// system power state S1.
		/// </summary>
		PowerSystemSleeping1,

		/// <summary>
		/// Indicates a system sleeping state less than PowerSystemSleeping1 and greater than PowerSystemSleeping3, which corresponds to
		/// system power state S2.
		/// </summary>
		PowerSystemSleeping2,

		/// <summary>
		/// Indicates a system sleeping state less than PowerSystemSleeping2 and greater than PowerSystemHibernate, which corresponds to
		/// system power state S3.
		/// </summary>
		PowerSystemSleeping3,

		/// <summary>Indicates the lowest-powered sleeping state, which corresponds to system power state S4.</summary>
		PowerSystemHibernate,

		/// <summary>Indicates the system is turned off, which corresponds to system shutdown state S5.</summary>
		PowerSystemShutdown,

		/// <summary>
		/// The number of system power state values for this enumeration type that represents actual power states. This value is the
		/// number of elements in the DeviceState member of the DEVICE_CAPABILITIES structure for a device. The other system power state
		/// values are less than this value.
		/// </summary>
		PowerSystemMaximum,
	}

	/// <summary>
	/// <para>
	/// The <c>CM_FULL_RESOURCE_DESCRIPTOR</c> structure specifies a set of system hardware resources of various types, assigned to a device
	/// that is connected to a specific bus. This structure is contained within a CM_RESOURCE_LIST structure.
	/// </para>
	/// </summary>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_cm_full_resource_descriptor typedef struct
	// _CM_FULL_RESOURCE_DESCRIPTOR { INTERFACE_TYPE InterfaceType; ULONG BusNumber; CM_PARTIAL_RESOURCE_LIST PartialResourceList; }
	// CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
	[PInvokeData("wdm.h", MSDNShortId = "e405c545-da0c-4b47-84c2-dd26d746da94")]
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct CM_FULL_RESOURCE_DESCRIPTOR
	{
		/// <summary>
		/// Specifies the type of bus to which the device is connected. This must be one of the types defined by INTERFACE_TYPE, in Wdm.h or
		/// Ntddk.h. (Not used by WDM drivers.)
		/// </summary>
		public INTERFACE_TYPE InterfaceType;

		/// <summary>
		/// The system-assigned, driver-supplied, zero-based number of the bus to which the device is connected. (Not used by WDM drivers.)
		/// </summary>
		public uint BusNumber;

		/// <summary>A CM_PARTIAL_RESOURCE_LIST structure.</summary>
		public CM_PARTIAL_RESOURCE_LIST PartialResourceList;
	}

	/// <summary>
	/// The <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> structure specifies one or more system hardware resources, of a single type, assigned to a
	/// device. This structure is used to create an array within a CM_PARTIAL_RESOURCE_LIST structure.
	/// </summary>
	/// <remarks>
	/// A <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> structure can describe either a raw (bus-relative) resource or a translated (system
	/// physical) resource, depending on the routine or IRP with which it is being used. For more information, see Raw and Translated
	/// Resources and IRP_MN_START_DEVICE.
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_cm_partial_resource_descriptor typedef struct
	// _CM_PARTIAL_RESOURCE_DESCRIPTOR { UCHAR Type; UCHAR ShareDisposition; USHORT Flags; union { struct { long Start; ULONG Length; }
	// Generic; struct { long Start; ULONG Length; } Port; struct { #if ... USHORT Level; USHORT Group; #else ULONG Level; #endif ULONG
	// Vector; UIntPtr Affinity; } Interrupt; struct { union { struct { USHORT Group; USHORT Reserved; USHORT MessageCount; ULONG Vector;
	// UIntPtr Affinity; } Raw; struct { #if ... USHORT Level; USHORT Group; #else ULONG Level; #endif ULONG Vector; UIntPtr Affinity; }
	// Translated; } DUMMYUNIONNAME; } MessageInterrupt; struct { long Start; ULONG Length; } Memory; struct { ULONG Channel; ULONG Port;
	// ULONG Reserved1; } Dma; struct { ULONG Channel; ULONG RequestLine; UCHAR TransferWidth; UCHAR Reserved1; UCHAR Reserved2; UCHAR
	// Reserved3; } DmaV3; struct { ULONG Data[3]; } DevicePrivate; struct { ULONG Start; ULONG Length; ULONG Reserved; } BusNumber; struct
	// { ULONG DataSize; ULONG Reserved1; ULONG Reserved2; } DeviceSpecificData; struct { long Start; ULONG Length40; } Memory40; struct {
	// long Start; ULONG Length48; } Memory48; struct { long Start; ULONG Length64; } Memory64; struct { UCHAR Class; UCHAR Type; UCHAR
	// Reserved1; UCHAR Reserved2; ULONG IdLowPart; ULONG IdHighPart; } Connection; } u; } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
	[PInvokeData("wdm.h", MSDNShortId = "96bf7bab-b8f5-439c-8717-ea6956ed0213")]
	[StructLayout(LayoutKind.Sequential)]
	public struct CM_PARTIAL_RESOURCE_DESCRIPTOR
	{
		public const ulong CM_RESOURCE_MEMORY_LARGE_40_MAXLEN = 0x000000FFFFFFFF00;
		public const ulong CM_RESOURCE_MEMORY_LARGE_48_MAXLEN = 0x0000FFFFFFFF0000;
		public const ulong CM_RESOURCE_MEMORY_LARGE_64_MAXLEN = 0xFFFFFFFF00000000;

		/// <summary>
		/// <para>
		/// Identifies the resource type. The constant value specified for <c>Type</c> indicates which structure within the <c>u</c> union
		/// is valid, as indicated in the following table. (These flags are used within both <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> and
		/// IO_RESOURCE_DESCRIPTOR structures, except where noted.)
		/// </para>
		/// <list type="table">
		/// <listheader>
		/// <term>Type value</term>
		/// <term>u member substructure</term>
		/// </listheader>
		/// <item>
		/// <term>CmResourceTypePort</term>
		/// <term>u.Port</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeInterrupt</term>
		/// <term>
		/// u.Interrupt or u.MessageInterrupt.If the CM_RESOURCE_INTERRUPT_MESSAGE flag of Flags is set, use u.MessageInterrupt; otherwise,
		/// use u.Interrupt.
		/// </term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeMemory</term>
		/// <term>u.Memory</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeMemoryLarge</term>
		/// <term>
		/// One of u.Memory40, u.Memory48, or u.Memory64.The CM_RESOURCE_MEMORY_LARGE_XXX flags set in the Flags member determines which
		/// structure is used.
		/// </term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeDma</term>
		/// <term>u.Dma (if CM_RESOURCE_DMA_V3 is not set) or u.DmaV3 (if CM_RESOURCE_DMA_V3 flag is set)</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeDevicePrivate</term>
		/// <term>u.DevicePrivate</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeBusNumber</term>
		/// <term>u.BusNumber</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeDeviceSpecific</term>
		/// <term>u.DeviceSpecificData(Not used within IO_RESOURCE_DESCRIPTOR.)</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypePcCardConfig</term>
		/// <term>u.DevicePrivate</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeMfCardConfig</term>
		/// <term>u.DevicePrivate</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeConnection</term>
		/// <term>u.Connection</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeConfigData</term>
		/// <term>Reserved for system use.</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeNonArbitrated</term>
		/// <term>Not used.</term>
		/// </item>
		/// </list>
		/// </summary>
		public CmResourceType Type;

		/// <summary>
		/// <para>Indicates whether the described resource can be shared. Valid constant values are listed in the following table.</para>
		/// <list type="table">
		/// <listheader>
		/// <term>Value</term>
		/// <term>Meaning</term>
		/// </listheader>
		/// <item>
		/// <term>CmResourceShareDeviceExclusive</term>
		/// <term>The device requires exclusive use of the resource.</term>
		/// </item>
		/// <item>
		/// <term>CmResourceShareDriverExclusive</term>
		/// <term>The driver requires exclusive use of the resource. (Not supported for WDM drivers.)</term>
		/// </item>
		/// <item>
		/// <term>CmResourceShareShared</term>
		/// <term>The resource can be shared without restriction.</term>
		/// </item>
		/// </list>
		/// </summary>
		public CM_SHARE_DISPOSITION ShareDisposition;

		/// <summary>
		/// <para>
		/// Contains flag bits that are specific to the resource type, as indicated in the following table. Flags can be bitwise-ORed
		/// together as appropriate.
		/// </para>
		/// <list type="table">
		/// <listheader>
		/// <term>Resource type</term>
		/// <term>Flag</term>
		/// <term>Definition</term>
		/// </listheader>
		/// <item>
		/// <term>CmResourceTypePort</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_MEMORY</term>
		/// <term>The device is accessed in memory address space.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_IO</term>
		/// <term>The device is accessed in I/O address space.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_10_BIT_DECODE</term>
		/// <term>The device decodes 10 bits of the port address.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_12_BIT_DECODE</term>
		/// <term>The device decodes 12 bits of the port address.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_16_BIT_DECODE</term>
		/// <term>The device decodes 16 bits of the port address.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_POSITIVE_DECODE</term>
		/// <term>
		/// The device uses "positive decode" instead of "subtractive decode". (In general, PCI devices use positive decode and ISA buses
		/// use subtractive decode.)
		/// </term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_PASSIVE_DECODE</term>
		/// <term>The device decodes the port but the driver does not use it.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_PORT_WINDOW_DECODE</term>
		/// <term/>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeInterrupt</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE</term>
		/// <term>The IRQ line is level-triggered. (These IRQs are usually sharable.)</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_LATCHED</term>
		/// <term>The IRQ line is edge-triggered.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_MESSAGE</term>
		/// <term>
		/// If this flag is set, the interrupt is a message-signaled interrupt. Otherwise, the interrupt is a line-based interrupt. This
		/// flag can be set starting with Windows Vista.
		/// </term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_POLICY_INCLUDED</term>
		/// <term>Not used with the CM_PARTIAL_RESOURCE_DESCRIPTOR structure. For more information about this flag, see IO_RESOURCE_DESCRIPTOR.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_SECONDARY_INTERRUPT</term>
		/// <term>
		/// The interrupt is a secondary interrupt. This flag can be set starting with Windows 8. For more information about secondary
		/// interrupts, see GPIO Interrupts.
		/// </term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_INTERRUPT_WAKE_HINT</term>
		/// <term>
		/// The interrupt is capable of waking the operating system from a low-power idle state or a system sleep state. This flag can be
		/// set starting with Windows 8. For more information about wake capabilities, see Enabling Device Wake-Up.
		/// </term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeMemory</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_READ_WRITE</term>
		/// <term>The memory range is readable and writable.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_READ_ONLY</term>
		/// <term>The memory range is read-only.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_WRITE_ONLY</term>
		/// <term>The memory range is write-only.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_PREFETCHABLE</term>
		/// <term>The memory range is prefetchable.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_COMBINEDWRITE</term>
		/// <term>Combined-write caching is allowed.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_24</term>
		/// <term>The device uses 24-bit addressing.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_CACHEABLE</term>
		/// <term>The memory range is cacheable.</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeMemoryLarge</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_LARGE_40</term>
		/// <term>The memory descriptor uses the u.Memory40 member.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_LARGE_48</term>
		/// <term>The memory descriptor uses the u.Memory48 member.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_MEMORY_LARGE_64</term>
		/// <term>The memory descriptor uses the u.Memory64 member.</term>
		/// </item>
		/// <item>
		/// <term>CmResourceTypeDma</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_8</term>
		/// <term>8-bit DMA channel</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_16</term>
		/// <term>16-bit DMA channel</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_32</term>
		/// <term>32-bit DMA channel</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_8_AND_16</term>
		/// <term>8-bit and 16-bit DMA channel</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_BUS_MASTER</term>
		/// <term>The device supports bus master DMA transfers.</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_TYPE_A</term>
		/// <term>Type A DMA</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_TYPE_B</term>
		/// <term>Type B DMA</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_TYPE_F</term>
		/// <term>Type F DMA</term>
		/// </item>
		/// <item>
		/// <term/>
		/// <term>CM_RESOURCE_DMA_V3</term>
		/// <term>Use the DmaV3 member instead of the Dma member. The DmaV3 member is available starting with Windows 8.</term>
		/// </item>
		/// </list>
		/// </summary>
		public CM_RESOURCE Flags;

		/// <summary>The union</summary>
		public union u;

		/// <summary>The union</summary>
		[StructLayout(LayoutKind.Explicit)]
#pragma warning disable IDE1006 // Naming Styles
		public struct union
#pragma warning restore IDE1006 // Naming Styles
		{
			/// <summary>The generic</summary>
			[FieldOffset(0)]
			public Generic Generic;

			/// <summary>The port</summary>
			[FieldOffset(0)]
			public Generic Port;

			/// <summary>The interrupt</summary>
			[FieldOffset(0)]
			public Interrupt Interrupt;

			/// <summary>The message interrupt raw</summary>
			[FieldOffset(0)]
			public MessageInterruptRaw MessageInterruptRaw;

			/// <summary>The message interrupt translated</summary>
			[FieldOffset(0)]
			public Interrupt MessageInterruptTranslated;

			/// <summary>The memory</summary>
			[FieldOffset(0)]
			public Generic Memory;

			/// <summary>The dma</summary>
			[FieldOffset(0)]
			public Dma Dma;

			/// <summary>The dma v3</summary>
			[FieldOffset(0)]
			public DmaV3 DmaV3;

			/// <summary>The device private</summary>
			[FieldOffset(0)]
			public DevicePrivate DevicePrivate;

			/// <summary>The bus number</summary>
			[FieldOffset(0)]
			public BusNumber BusNumber;

			/// <summary>The device specific data</summary>
			[FieldOffset(0)]
			public DeviceSpecificData DeviceSpecificData;

			/// <summary>The memory40</summary>
			[FieldOffset(0)]
			public Memory40 Memory40;

			/// <summary>The memory48</summary>
			[FieldOffset(0)]
			public Memory48 Memory48;

			/// <summary>The memory64</summary>
			[FieldOffset(0)]
			public Memory64 Memory64;

			/// <summary>The connection</summary>
			[FieldOffset(0)]
			public Connection Connection;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct Generic
		{
			/// <summary>
			/// <para>
			/// For raw resources: Specifies the bus-relative physical address of the lowest of a range of contiguous I/O port addresses
			/// allocated to the device.
			/// </para>
			/// <para>
			/// For translated resources: Specifies the system physical address of the lowest of a range of contiguous I/O port addresses
			/// allocated to the device.
			/// </para>
			/// <para>For more information about raw and translated resources, see Remarks.</para>
			/// </summary>
			public long Start;

			/// <summary>The length, in bytes, of the range of allocated I/O port addresses.</summary>
			public uint Length;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		public struct Interrupt
		{
			/// <summary>The level</summary>
			public ushort Level;

			/// <summary>
			/// Specifies the processor group number. This member exists only if the NT_PROCESSOR_GROUPS constant is defined at compile
			/// time. This member can be nonzero only on Windows 7 and later versions of Windows. The <c>Group</c> and <c>Affinity</c>
			/// members together specify a group affinity that indicates which processors the device can interrupt. To specify an affinity
			/// for any group, set <c>Group</c> to ALL_PROCESSOR_GROUPS.
			/// </summary>
			public ushort Group;

			/// <summary>
			/// <para>For raw resources: Specifies the device's bus-specific interrupt vector (if appropriate for the platform and bus).</para>
			/// <para>For translated resources: Specifies the global system interrupt vector assigned to the device.</para>
			/// <para>For more information about raw and translated resources, see Remarks.</para>
			/// </summary>
			public uint Vector;

			/// <summary>
			/// Contains a <c>UIntPtr</c>-typed bitmask value indicating the set of processors the device can interrupt. To indicate that
			/// the device can interrupt any processor, this member is set to -1.
			/// </summary>
			public UIntPtr Affinity;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		public struct MessageInterruptRaw
		{
			/// <summary>
			/// Specifies a processor group number. This member exists only if NT_PROCESSOR_GROUPS is defined at compile time. This member
			/// can be nonzero only on Windows 7 and later versions of Windows. The <c>Group</c> and <c>Affinity</c> members together
			/// specify a group affinity that indicates which processors can receive the device's interrupts. To specify an affinity for any
			/// group, set <c>Group</c> to ALL_PROCESSOR_GROUPS.
			/// </summary>
			public ushort Group;

			/// <summary>Specifies the number of message-signaled interrupts generated for this driver.</summary>
			public ushort MessageCount;

			/// <summary>Specifies the device's interrupt vector.</summary>
			public uint Vector;

			/// <summary>Specifies a UIntPtr value that indicates the processors that receive the device's interrupts.</summary>
			public UIntPtr Affinity;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct Dma
		{
			/// <summary>Specifies the number of the DMA channel on a system DMA controller that the device can use.</summary>
			public uint Channel;

			/// <summary>Specifies the number of the DMA port that an MCA-type device can use.</summary>
			public uint Port;

			/// <summary>Not used.</summary>
			public uint Reserved1;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct DmaV3
		{
			/// <summary>Specifies the number of the DMA channel on the system DMA controller that is allocated to the device.</summary>
			public uint Channel;

			/// <summary>Specifies the number of the request line on the system DMA controller that is allocated to the device.</summary>
			public uint RequestLine;

			/// <summary>
			/// Specifies the width, in bits, of the data bus that the system DMA controller that is allocated to the device uses to
			/// transfer data to or from the device.
			/// </summary>
			public byte TransferWidth;

			/// <summary>Not used.</summary>
			public byte Reserved1;

			/// <summary>Not used.</summary>
			public byte Reserved2;

			/// <summary>Not used.</summary>
			public byte Reserved3;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct DevicePrivate
		{
			private uint data0, data1, data2;

			/// <summary>The data</summary>
			public uint[] Data
			{
				get => new[] { data0, data1, data2 };
				set
				{
					data0 = value[0];
					data1 = value[1];
					data2 = value[2];
				}
			}
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct BusNumber
		{
			/// <summary>Specifies the lowest-numbered of a range of contiguous buses allocated to the device.</summary>
			public uint Start;

			/// <summary>Specifies the number of buses allocated to the device.</summary>
			public uint Length;

			/// <summary>Not used.</summary>
			public uint Reserved;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct DeviceSpecificData
		{
			/// <summary>Specifies the number of bytes appended to the end of the <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> structure.</summary>
			public uint DataSize;

			/// <summary>Not used.</summary>
			public uint Reserved1;

			/// <summary>Not used.</summary>
			public uint Reserved2;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct Memory40
		{
			/// <summary>
			/// <para>
			/// For raw resources: Specifies the bus-relative physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>
			/// For translated resources: Specifies the system physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>For more information about raw and translated resources, see Remarks.</para>
			/// </summary>
			public long Start;

			/// <summary>
			/// Contains the high 32 bits of the 40-bit length, in bytes, of the range of allocated memory addresses. The lowest 8 bits are
			/// treated as zero.
			/// </summary>
			public uint Length40;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct Memory48
		{
			/// <summary>
			/// <para>
			/// For raw resources: Specifies the bus-relative physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>
			/// For translated resources: Specifies the system physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>For more information about raw and translated resources, see Remarks.</para>
			/// </summary>
			public long Start;

			/// <summary>
			/// Contains the high 32 bits of the 48-bit length, in bytes, of the range of allocated memory addresses. The lowest 16 bits are
			/// treated as zero.
			/// </summary>
			public uint Length48;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct Memory64
		{
			/// <summary>
			/// <para>
			/// For raw resources: Specifies the bus-relative physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>
			/// For translated resources: Specifies the system physical address of the lowest of a range of contiguous memory addresses that
			/// are allocated to the device.
			/// </para>
			/// <para>For more information about raw and translated resources, see Remarks.</para>
			/// </summary>
			public long Start;

			/// <summary>
			/// Contains the high 32 bits of the 64-bit length, in bytes, of the range of allocated memory addresses. The lowest 32 bits are
			/// treated as zero.
			/// </summary>
			public uint Length64;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct Connection
		{
			/// <summary>
			/// <para>Specifies the connection class. This member is set to one of the following values.</para>
			/// <list type="table">
			/// <listheader>
			/// <term>Value</term>
			/// <term>Meaning</term>
			/// </listheader>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_CLASS_GPIO</term>
			/// <term>Access the device through one or more pins on a GPIO controller.</term>
			/// </item>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_CLASS_SERIAL</term>
			/// <term>Access the device through a serial bus or serial port.</term>
			/// </item>
			/// </list>
			/// </summary>
			public byte Class;

			/// <summary>
			/// <para>Specifies the connection type.</para>
			/// <para>If <c>Class</c> = CM_RESOURCE_CONNECTION_CLASS_GPIO, <c>Type</c> is set to the following value.</para>
			/// <list type="table">
			/// <listheader>
			/// <term>Value</term>
			/// <term>Meaning</term>
			/// </listheader>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_TYPE_GPIO_IO</term>
			/// <term>Access the device through GPIO pins that are configured for I/O.</term>
			/// </item>
			/// </list>
			/// <para>If <c>Class</c> = CM_RESOURCE_CONNECTION_CLASS_SERIAL, <c>Type</c> is set to one of the following values.</para>
			/// <list type="table">
			/// <listheader>
			/// <term>Value</term>
			/// <term>Meaning</term>
			/// </listheader>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C</term>
			/// <term>The device is connected to an I²C bus.</term>
			/// </item>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_TYPE_SERIAL_SPI</term>
			/// <term>The device is connected to an SPI bus.</term>
			/// </item>
			/// <item>
			/// <term>CM_RESOURCE_CONNECTION_TYPE_SERIAL_UART</term>
			/// <term>The device is connected to a serial port.</term>
			/// </item>
			/// </list>
			/// </summary>
			public byte Type;

			/// <summary>Not used.</summary>
			public byte Reserved1;

			/// <summary>Not used.</summary>
			public byte Reserved2;

			/// <summary>Contains the lower 32 bits of the 64-bit connection ID.</summary>
			public uint IdLowPart;

			/// <summary>Contains the upper 32 bits of the 64-bit connection ID.</summary>
			public uint IdHighPart;
		}
	}

	/// <summary>
	/// <para>
	/// The <c>CM_PARTIAL_RESOURCE_LIST</c> structure specifies a set of system hardware resources, of various types, assigned to a device.
	/// This structure is contained within a CM_FULL_RESOURCE_DESCRIPTOR structure.
	/// </para>
	/// </summary>
	/// <remarks>
	/// <para>
	/// This structure is the header for an array of <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> structures. The <c>PartialDescriptors</c> member
	/// contains the first element in this array, and the <c>Count</c> member specifies the total number of array elements. If the array
	/// contains more than one element, the remaining elements in the array immediately follow the <c>CM_PARTIAL_RESOURCE_LIST</c> structure
	/// in memory. The total number of bytes occupied by the <c>CM_PARTIAL_RESOURCE_LIST</c> structure and any array elements that follow
	/// this structure is <c>sizeof</c>( <c>CM_PARTIAL_RESOURCE_LIST</c>) + ( <c>Count</c> - 1) * <c>sizeof</c>( <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c>).
	/// </para>
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_cm_partial_resource_list typedef struct
	// _CM_PARTIAL_RESOURCE_LIST { USHORT Version; USHORT Revision; ULONG Count; CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; }
	// CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
	[PInvokeData("wdm.h", MSDNShortId = "f16b26f5-1f32-4c2e-83ec-0a0f79a4be85")]
	[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<CM_PARTIAL_RESOURCE_LIST>), nameof(Count))]
	[StructLayout(LayoutKind.Sequential)]
	public struct CM_PARTIAL_RESOURCE_LIST
	{
		/// <summary>The version number of this structure. This value should be 1.</summary>
		public ushort Version;

		/// <summary>The revision of this structure. This value should be 1.</summary>
		public ushort Revision;

		/// <summary>The number of elements contained in the <c>PartialDescriptors</c> array.</summary>
		public uint Count;

		/// <summary>The first element in an array of one or more CM_PARTIAL_RESOURCE_DESCRIPTOR structures.</summary>
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
		public CM_PARTIAL_RESOURCE_DESCRIPTOR[] PartialDescriptors;
	}

	/// <summary>The <c>CM_POWER_DATA</c> structure contains information about a device's power management state and capabilities.</summary>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-cm_power_data_s typedef struct CM_Power_Data_s { ULONG
	// PD_Size; DEVICE_POWER_STATE PD_MostRecentPowerState; ULONG PD_Capabilities; ULONG PD_D1Latency; ULONG PD_D2Latency; ULONG
	// PD_D3Latency; DEVICE_POWER_STATE PD_PowerStateMapping[POWER_SYSTEM_MAXIMUM]; SYSTEM_POWER_STATE PD_DeepestSystemWake; }
	// CM_POWER_DATA, *PCM_POWER_DATA;
	[PInvokeData("wdm.h", MSDNShortId = "NS:wdm.CM_Power_Data_s")]
	[StructLayout(LayoutKind.Sequential)]
	public struct CM_POWER_DATA
	{
		/// <summary>The size, in bytes, of this structure.</summary>
		public uint PD_Size;

		/// <summary>A DEVICE_POWER_STATE value representing the device's most recent power state.</summary>
		public DEVICE_POWER_STATE PD_MostRecentPowerState;

		/// <summary>
		/// <para>The device's power capabilities, represented by a combination of the following bit flags:</para>
		/// <para>PDCAP_D0_SUPPORTED</para>
		/// <para>PDCAP_D1_SUPPORTED</para>
		/// <para>PDCAP_D2_SUPPORTED</para>
		/// <para>PDCAP_D3_SUPPORTED</para>
		/// <para>PDCAP_WAKE_FROM_D0_SUPPORTED</para>
		/// <para>PDCAP_WAKE_FROM_D1_SUPPORTED</para>
		/// <para>PDCAP_WAKE_FROM_D2_SUPPORTED</para>
		/// <para>PDCAP_WAKE_FROM_D3_SUPPORTED</para>
		/// <para>PDCAP_WARM_EJECT_SUPPORTED</para>
		/// </summary>
		public PDCAP PD_Capabilities;

		/// <summary>
		/// The device's latency when returning the D0 state from the D1 state. For more information, see the <c>D1Latency</c> member of DEVICE_CAPABILITIES.
		/// </summary>
		public uint PD_D1Latency;

		/// <summary>
		/// The device's latency when returning the D0 state from the D2 state. For more information, see the <c>D2Latency</c> member of <c>DEVICE_CAPABILITIES</c>.
		/// </summary>
		public uint PD_D2Latency;

		/// <summary>
		/// The device's latency when returning the D0 state from the D3 state. For more information, see the <c>D3Latency</c> member of <c>DEVICE_CAPABILITIES</c>.
		/// </summary>
		public uint PD_D3Latency;

		/// <summary>
		/// An array of <c>DEVICE_POWER_STATE</c> values representing the maximum device power state achievable for each system power state.
		/// For more information, see the <c>DeviceState</c> member of DEVICE_CAPABILITIES.
		/// </summary>
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)SYSTEM_POWER_STATE.PowerSystemMaximum)]
		public DEVICE_POWER_STATE[] PD_PowerStateMapping;

		/// <summary>
		/// Specifies the least-powered system state from which the device can wake the system. <c>PD_DeepestSystemWake</c> typically
		/// indicates one of the system sleeping states, S1, S2, or S3 (as specified by <c>PowerSystemSleeping1</c>,
		/// <c>PowerSystemSleeping2</c>, and <c>PowerSystemSleeping3</c>, respectively). Note, however, that some devices might be able to
		/// wake the system from the system hibernate state, S4 (as specified by <c>PowerSystemHibernate</c>), or even from the system
		/// shutdown state, S5 (as specified by <c>PowerSystemShutdown</c>).
		/// </summary>
		public SYSTEM_POWER_STATE PD_DeepestSystemWake;
	}

	/// <summary>The <c>CM_RESOURCE_LIST</c> structure specifies all of the system hardware resources assigned to a device.</summary>
	/// <remarks>
	/// <para>
	/// This structure describes the assignment of hardware resources to a device. An IRP_MN_START_DEVICE IRP uses this structure to specify
	/// the resources that the Plug and Play manager assigns to a device. Drivers for legacy devices use this structure to pass their
	/// resource requirements to the IoReportResourceForDetection routine. For more information about hardware resource allocation, see
	/// Hardware Resources.
	/// </para>
	/// <para>
	/// The <c>CM_RESOURCE_LIST</c> structure is a header for a larger data structure, of variable size, that contains one or more full
	/// resource descriptors. All of the data in this larger structure occupies a contiguous block of memory. Each full resource descriptor
	/// occupies a subblock within the larger block.
	/// </para>
	/// <para>
	/// A full resource descriptor begins with a CM_FULL_RESOURCE_DESCRIPTOR structure, which serves as a header for an array of
	/// CM_PARTIAL_RESOURCE_DESCRIPTOR structures. The length of this array determines the size of the full resource descriptor. The last
	/// member in the <c>CM_FULL_RESOURCE_DESCRIPTOR</c> structure is a CM_PARTIAL_RESOURCE_LIST structure that contains, as its last
	/// member, the first element in this array. If the array contains more than one element, the remaining elements immediately follow, in
	/// memory, the end of the <c>CM_PARTIAL_RESOURCE_LIST</c> structure, which is also the end of the <c>CM_FULL_RESOURCE_DESCRIPTOR</c> structure.
	/// </para>
	/// <para>
	/// Driver code can use pointer arithmetic to step from one full resource descriptor to the next. For example, if a parameter named list
	/// is a pointer to the <c>CM_FULL_RESOURCE_DESCRIPTOR</c> structure at the start of one full resource descriptor, list can be updated
	/// to point to the start of the next full resource descriptor as follows:
	/// </para>
	/// <para>
	/// In this example, is a pointer to the start of the <c>CM_PARTIAL_RESOURCE_DESCRIPTOR</c> array, and is the number of elements in the
	/// array. For more information about the <c>PartialDescriptors</c> and <c>Count</c> members, see CM_PARTIAL_RESOURCE_LIST. ####
	/// Examples All PnP drivers must handle IRP_MN_START_DEVICE IRPs. Typically, a driver's handler for this IRP walks the lists of
	/// assigned resources that are pointed to by the <c>Parameters.StartDevice.AllocatedResources</c> and
	/// <c>Parameters.StartDevice.AllocatedResourcesTranslated</c> members of the IO_STACK_LOCATION structure in the IRP. The following code
	/// example contains a function—named GetAssignedResources—that is called in the handler to walk each list. This function verifies that
	/// the required resources are specified in the list, and configures the device to use the resources. The GetAssignedResources function
	/// returns <c>TRUE</c> if it succeeds. Otherwise, it returns <c>FALSE</c> (probably from the <c>switch</c> statement, although the
	/// details are omitted to simplify the code example).
	/// </para>
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_cm_resource_list typedef struct _CM_RESOURCE_LIST {
	// ULONG Count; CM_FULL_RESOURCE_DESCRIPTOR List[1]; } CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
	[PInvokeData("wdm.h", MSDNShortId = "01f31255-a4f7-4a16-9238-a7391bb850d1")]
	[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<CM_RESOURCE_LIST>), nameof(Count))]
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct CM_RESOURCE_LIST
	{
		/// <summary>
		/// The number of full resource descriptors that are specified by this <c>CM_RESOURCE_LIST</c> structure. The <c>List</c> member is
		/// the header for the first full resource descriptor. For WDM drivers, <c>Count</c> is always 1.
		/// </summary>
		public uint Count;

		/// <summary>
		/// The CM_FULL_RESOURCE_DESCRIPTOR structure that serves as the header for the first full resource descriptor. If the
		/// <c>CM_RESOURCE_LIST</c> structure contains more than one full resource descriptor, the second full resource descriptor
		/// immediately follows the first in memory, and so on. The size of each full resource descriptor depends on the length of the
		/// CM_PARTIAL_RESOURCE_DESCRIPTOR array that it contains. For more information, see the following Remarks section.
		/// </summary>
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
		public CM_FULL_RESOURCE_DESCRIPTOR[] List;
	}

	/// <summary>
	/// A <c>DEVICE_CAPABILITIES</c> structure describes PnP and power capabilities of a device. This structure is returned in response to
	/// an IRP_MN_QUERY_CAPABILITIES IRP.
	/// </summary>
	/// <remarks>
	/// <para>
	/// Bus drivers set the appropriate values in this structure in response to an <c>IRP_MN_QUERY_CAPABILITIES</c> IRP. Bus filter drivers,
	/// function drivers, and filter drivers might alter the capabilities set by the bus driver.
	/// </para>
	/// <para>
	/// Drivers that send an <c>IRP_MN_QUERY_CAPABILITIES</c> request must initialize the <c>Size</c>, <c>Version</c>, <c>Address</c>, and
	/// <c>UINumber</c> members of this structure before sending the IRP.
	/// </para>
	/// <para>
	/// For more information about using the <c>DEVICE_CAPABILITIES</c> structure to describe a device's power capabilities, see Reporting
	/// Device Power Capabilities.
	/// </para>
	/// </remarks>
	// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_device_capabilities typedef struct _DEVICE_CAPABILITIES {
	// USHORT Size; USHORT Version; ULONG DeviceD1 : 1; ULONG DeviceD2 : 1; ULONG LockSupported : 1; ULONG EjectSupported : 1; ULONG
	// Removable : 1; ULONG DockDevice : 1; ULONG UniqueID : 1; ULONG SilentInstall : 1; ULONG RawDeviceOK : 1; ULONG SurpriseRemovalOK : 1;
	// ULONG WakeFromD0 : 1; ULONG WakeFromD1 : 1; ULONG WakeFromD2 : 1; ULONG WakeFromD3 : 1; ULONG HardwareDisabled : 1; ULONG NonDynamic
	// : 1; ULONG WarmEjectSupported : 1; ULONG NoDisplayInUI : 1; ULONG Reserved1 : 1; ULONG WakeFromInterrupt : 1; ULONG SecureDevice : 1;
	// ULONG ChildOfVgaEnabledBridge : 1; ULONG DecodeIoOnBoot : 1; ULONG Reserved : 9; ULONG Address; ULONG UINumber; DEVICE_POWER_STATE
	// DeviceState[POWER_SYSTEM_MAXIMUM]; SYSTEM_POWER_STATE SystemWake; DEVICE_POWER_STATE DeviceWake; ULONG D1Latency; ULONG D2Latency;
	// ULONG D3Latency; } DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
	[PInvokeData("wdm.h", MSDNShortId = "NS:wdm._DEVICE_CAPABILITIES")]
	[StructLayout(LayoutKind.Sequential)]
	public struct DEVICE_CAPABILITIES
	{
		/// <summary>
		/// Specifies the size of the structure, in bytes. This field is set by the component that sends the
		/// <c>IRP_MN_QUERY_CAPABILITIES</c> request.
		/// </summary>
		public ushort Size;

		/// <summary>
		/// Specifies the version of the structure, currently version 1. This field is set by the component that sends the
		/// <c>IRP_MN_QUERY_CAPABILITIES</c> request.
		/// </summary>
		public ushort Version;

		private uint _flags;

		/// <summary>Specifies whether the device hardware supports the D1 power state. Drivers should not change this value.</summary>
		public bool DeviceD1 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 0); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 0, value); }

		/// <summary>Specifies whether the device hardware supports the D2 power state. Drivers should not change this value.</summary>
		public bool DeviceD2 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 1); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 1, value); }

		/// <summary>
		/// Specifies whether the device supports physical-device locking that prevents device ejection. This member pertains to ejecting
		/// the device from its slot, rather than ejecting a piece of removable media from the device.
		/// </summary>
		public bool LockSupported { get => Vanara.Extensions.BitHelper.GetBit(_flags, 2); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 2, value); }

		/// <summary>
		/// Specifies whether the device supports software-controlled device ejection while the system is in the <c>PowerSystemWorking</c>
		/// state. This member pertains to ejecting the device from its slot, rather than ejecting a piece of removable media from the device.
		/// </summary>
		public bool EjectSupported { get => Vanara.Extensions.BitHelper.GetBit(_flags, 3); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 3, value); }

		/// <summary>
		/// <para>
		/// Specifies whether the device can be dynamically removed from its immediate parent. If <c>Removable</c> is set to <c>TRUE</c>,
		/// the device does not belong to the same physical object as its parent.
		/// </para>
		/// <para>
		/// For example, if <c>Removable</c> is set to <c>TRUE</c> for a USB composite device inside a multifunction printer, the composite
		/// device does not belong to the physical object of its immediate parent, such as a USB hub inside a notebook PC.
		/// </para>
		/// <para>
		/// In most cases the bus driver, not the function driver, should determine the value of the <c>Removable</c> parameter of the
		/// device. For USB devices, the USB hub driver sets the <c>Removable</c> parameter. It should not be modified by the function driver.
		/// </para>
		/// <para>
		/// If <c>Removable</c> is set to <c>TRUE</c>, the device is displayed in the <c>Unplug or Eject Hardware</c> program, unless
		/// <c>SurpriseRemovalOK</c> is also set to <c>TRUE</c>.
		/// </para>
		/// </summary>
		public bool Removable { get => Vanara.Extensions.BitHelper.GetBit(_flags, 4); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 4, value); }

		/// <summary>Specifies whether the device is a docking peripheral.</summary>
		public bool DockDevice { get => Vanara.Extensions.BitHelper.GetBit(_flags, 5); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 5, value); }

		/// <summary>
		/// Specifies whether the device's instance ID is unique system-wide. This bit is clear if the instance ID is unique only within the
		/// scope of the bus. For more information, see Device Identification Strings.
		/// </summary>
		public bool UniqueID { get => Vanara.Extensions.BitHelper.GetBit(_flags, 6); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 6, value); }

		/// <summary>
		/// Specifies whether Device Manager should suppress all installation dialog boxes; except required dialog boxes such as "no
		/// compatible drivers found."
		/// </summary>
		public bool SilentInstall { get => Vanara.Extensions.BitHelper.GetBit(_flags, 7); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 7, value); }

		/// <summary>
		/// Specifies whether the driver for the underlying bus can drive the device if there is no function driver (for example, SCSI
		/// devices in pass-through mode). This mode of operation is called raw mode.
		/// </summary>
		public bool RawDeviceOK { get => Vanara.Extensions.BitHelper.GetBit(_flags, 8); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 8, value); }

		/// <summary>
		/// <para>
		/// Specifies whether the function driver for the device can handle the case where the device is removed before Windows can send
		/// <c>IRP_MN_QUERY_REMOVE_DEVICE</c> to it. If <c>SurpriseRemovalOK</c> is set to <c>TRUE</c>, the device can be safely removed
		/// from its immediate parent regardless of the state that its driver is in.
		/// </para>
		/// <para>
		/// For example, a standard USB mouse does not maintain any state in its hardware and thus can be safely removed at any time.
		/// However, an external hard disk whose driver caches writes in memory cannot be safely removed without first letting the driver
		/// flush its cache to the hardware.
		/// </para>
		/// <para>
		/// <c>Note</c> Drivers for USB devices that support surprise removal must set this to <c>TRUE</c> only when the IRP is being passed
		/// back up the driver stack.
		/// </para>
		/// </summary>
		public bool SurpriseRemovalOK { get => Vanara.Extensions.BitHelper.GetBit(_flags, 9); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 9, value); }

		/// <summary>
		/// Specifies whether the device can respond to an external wake signal while in the D0 state. Drivers should not change this value.
		/// </summary>
		public bool WakeFromD0 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 10); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 10, value); }

		/// <summary>
		/// Specifies whether the device can respond to an external wake signal while in the D1 state. Drivers should not change this value.
		/// </summary>
		public bool WakeFromD1 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 11); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 11, value); }

		/// <summary>
		/// Specifies whether the device can respond to an external wake signal while in the D2 state. Drivers should not change this value.
		/// </summary>
		public bool WakeFromD2 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 12); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 12, value); }

		/// <summary>
		/// Specifies whether the device can respond to an external wake signal while in the D3 state. Drivers should not change this value.
		/// </summary>
		public bool WakeFromD3 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 13); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 13, value); }

		/// <summary>
		/// <para>When set, this flag specifies that the device's hardware is disabled.</para>
		/// <para>
		/// A device's parent bus driver or a bus filter driver sets this flag when such a driver determines that the device hardware is disabled.
		/// </para>
		/// <para>
		/// The PnP manager sends one <c>IRP_MN_QUERY_CAPABILITIES</c> IRP right after a device is enumerated and sends another after the
		/// device has been started. The PnP manager only checks this bit right after the device is enumerated. Once the device is started,
		/// this bit is ignored.
		/// </para>
		/// </summary>
		public bool HardwareDisabled { get => Vanara.Extensions.BitHelper.GetBit(_flags, 14); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 14, value); }

		/// <summary>Reserved for future use.</summary>
		public bool NonDynamic { get => Vanara.Extensions.BitHelper.GetBit(_flags, 15); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 15, value); }

		/// <summary>Reserved for future use.</summary>
		public bool WarmEjectSupported { get => Vanara.Extensions.BitHelper.GetBit(_flags, 16); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 16, value); }

		/// <summary>
		/// Do not display the device in the user interface. If this bit is set, the device is displayed in the user interface, even if the
		/// device is present but fails to start. Only bus drivers and associated bus filter drivers should set this bit. (Also see the
		/// <c>PNP_DEVICE_DONT_DISPLAY_IN_UI</c> flag in the PNP_DEVICE_STATE structure.)
		/// </summary>
		public bool NoDisplayInUI { get => Vanara.Extensions.BitHelper.GetBit(_flags, 17); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 17, value); }

		/// <summary>Reserved for system use.</summary>
		public bool Reserved1 { get => Vanara.Extensions.BitHelper.GetBit(_flags, 18); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 18, value); }

		/// <summary>
		/// Indicates whether the driver or ACPI is responsible for handling the wake event. If set, the driver is responsible for handling
		/// the wake event. ACPI arms the device when it receives an IRP_MN_WAIT_WAKE IRP, but does not connect the interrupt, complete the
		/// IRP to notify the device stack of a wake event.
		/// </summary>
		public bool WakeFromInterrupt { get => Vanara.Extensions.BitHelper.GetBit(_flags, 19); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 19, value); }

		/// <summary>Indicates whether the device is a secure device.</summary>
		public bool SecureDevice { get => Vanara.Extensions.BitHelper.GetBit(_flags, 20); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 20, value); }

		/// <summary>For a VGA device, indicates whether the parent bridge has the VGA decoding bit set.</summary>
		public bool ChildOfVgaEnabledBridge { get => Vanara.Extensions.BitHelper.GetBit(_flags, 21); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 21, value); }

		/// <summary>Indictates whether the device has IO decode enabled on boot.</summary>
		public bool DecodeIoOnBoot { get => Vanara.Extensions.BitHelper.GetBit(_flags, 22); set => Vanara.Extensions.BitHelper.SetBit(ref _flags, 22, value); }

		/// <summary>
		/// <para>Specifies an address indicating where the device is located on its underlying bus.</para>
		/// <para>
		/// The interpretation of this number is bus-specific. If the address is unknown or the bus driver does not support an address, the
		/// bus driver leaves this member at its default value of 0xFFFFFFFF.
		/// </para>
		/// <para>The following list describes the information certain bus drivers store in the <c>Address</c> field for their child devices:</para>
		/// <para>1394</para>
		/// <para>Does not supply an address because the addresses are volatile. Defaults to 0xFFFFFFFF.</para>
		/// <para>EISA</para>
		/// <para>Slot Number (0-F).</para>
		/// <para>IDE</para>
		/// <para>
		/// For an IDE device, the address contains the target ID and LUN. For an IDE channel, the address is zero or one (0 = primary
		/// channel and 1 = secondary channel).
		/// </para>
		/// <para>ISApnp</para>
		/// <para>Does not supply an address. Defaults to 0xFFFFFFFF.</para>
		/// <para>PC Card (PCMCIA)</para>
		/// <para>The socket number (typically 0x00 or 0x40).</para>
		/// <para>PCI</para>
		/// <para>The device number in the high word and the function number in the low word.</para>
		/// <para>SCSI</para>
		/// <para>The target ID.</para>
		/// <para>USB</para>
		/// <para>The port number.</para>
		/// </summary>
		public uint Address;

		/// <summary>
		/// <para>Specifies a number associated with the device that can be displayed in the user interface.</para>
		/// <para>
		/// This number is typically a user-perceived slot number, such as a number printed next to the slot on the board, or some other
		/// number that makes locating the physical device easier for the user. For buses with no such convention, or when the
		/// <c>UINumber</c> is unknown, the bus driver leaves this member at its default value of 0xFFFFFFFF.
		/// </para>
		/// </summary>
		public uint UINumber;

		/// <summary>
		/// <para>
		/// An array of values indicating the most-powered device power state that the device can maintain for each system power state. The
		/// <c>DeviceState[PowerSystemWorking]</c> element of the array corresponds to the S0 system state. The entry for
		/// <c>PowerSystemUnspecified</c> is reserved for system use.
		/// </para>
		/// <para>
		/// The entries in this array are based on the capabilities of the parent devnode. As a general rule, a driver should not change
		/// these values. However, if necessary, a driver can lower the value, for example, from <c>PowerDeviceD1</c> to <c>PowerDeviceD2</c>.
		/// </para>
		/// <para>
		/// If the bus driver is unable to determine the appropriate device power state for a root-enumerated device, it sets
		/// <c>DeviceState[PowerSystemWorking]</c> to <c>PowerDeviceD0</c> and all other entries to <c>PowerDeviceD3</c>.
		/// </para>
		/// </summary>
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)SYSTEM_POWER_STATE.PowerSystemMaximum)]
		public DEVICE_POWER_STATE[] DeviceState;

		/// <summary>
		/// <para>
		/// Specifies the least-powered system power state from which the device can signal a wake event. A value of
		/// <c>PowerSystemUnspecified</c> indicates that the device cannot wake the system.
		/// </para>
		/// <para>A bus driver can get this information from its parent devnode.</para>
		/// <para>
		/// In general, a driver should not change this value. If necessary, however, a driver can raise the power state, for example, from
		/// <c>PowerSystemHibernate</c> to <c>PowerSystemS1</c>, to indicate that its device cannot wake the system from a hibernation state
		/// but can from a higher-powered sleep state.
		/// </para>
		/// </summary>
		public SYSTEM_POWER_STATE SystemWake;

		/// <summary>
		/// Specifies the least-powered device power state from which the device can signal a wake event. A value of
		/// <c>PowerDeviceUnspecified</c> indicates that the device cannot signal a wake event.
		/// </summary>
		public DEVICE_POWER_STATE DeviceWake;

		/// <summary>
		/// Specifies the device's approximate worst-case latency, in 100-microsecond units, for returning the device to the
		/// <c>PowerDeviceD0</c> state from the <c>PowerDeviceD1</c> state. Set to zero if the device does not support the D1 state.
		/// </summary>
		public uint D1Latency;

		/// <summary>
		/// Specifies the device's approximate worst-case latency, in 100-microsecond units, for returning the device to the
		/// <c>PowerDeviceD0</c> state from the <c>PowerDeviceD2</c> state. Set to zero if the device does not support the D2 state.
		/// </summary>
		public uint D2Latency;

		/// <summary>
		/// Specifies the device's approximate worst-case latency, in 100-microsecond units, for returning the device to the
		/// <c>PowerDeviceD0</c> state from the <c>PowerDeviceD3</c> state. Set to zero if the device does not support the D3 state.
		/// </summary>
		public uint D3Latency;
	}
}